/***************************************************************************
 *   Copyright (C) 2005 by xihe   *
 *   xihels@163.com                                                        *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/
#ifndef _QQ_BUDDY_H_
#define _QQ_BUDDY_H_
#include "Packet.h"
#include <string>
using std::string;

struct QQGroupName {
    QQGroupName():
	group(0x00)
    {}
    QQGroupName(uint8_t _group, const char* _name) :
	group(_group),
	groupname(_name)
    {}

    explicit QQGroupName(const uint8_t* buf);
    int putBody(uint8_t* buf) const 
    {
	uint8_t* cur = buf;
	cur += writeBufB(cur, group);
	cur += writeBufData(cur,
		reinterpret_cast<const uint8_t* const>(groupname.c_str()), 
		groupname.size());
	return cur - buf;
    }
    string groupname;
    uint8_t group;
};

struct QQGroupFriend {
    QQGroupFriend(int _group, uint32_t _uid, uint8_t _type) :
	group(_group),
	uid(_uid),
	type(_type){}
    QQGroupFriend(const uint8_t* buf, int len) {
	readBufDw(uid, buf);
	readBufB(type, buf + 4);
	readBufB(group, buf + 5);
    }
    uint32_t uid;   // 好友的QQ号，或者是群的内部ID
    uint8_t  type;  // 好友类型，是好友，还是群
    uint8_t  group; // 好友所在的组
} ;


/**
 * 1. 好友QQ号，4字节
 * 2. 未知, 1字节
 * 3. 头像，1字节
 * 4. 年龄，1字节
 * 5. 性别，1字节
 * 6. 昵称长度，1字节
 * 7. 昵称，不定字节，由5指定
 * 8. 未知， 2节
 * 9. 1字节扩展标志，bit1表示是否有QQ Show，其他未知
 * 10.1字节通用标志
 *     bit1 => 会员
 *     bit4 => TCP方式登陆
 *     bit5 => 移动QQ
 *     bit6 => 绑定到手机
 *     bit7 => 是否有摄像头
 */

struct QQBuddy {
    int getBody(const uint8_t* buf, int len);
    string	    nickname;	// 呢称
    uint32_t	    uid;	// QQ号
    uint16_t	    face;	// 头像
    uint8_t	    age;	// 年龄
    uint8_t	    sex;	// 性别
    struct Extend {
	unsigned qqShow : 1;
    } extend;
    struct Common {
	unsigned member : 4;
	unsigned tcp  : 1;
	unsigned mobile : 1;
	unsigned phone  : 1;
	unsigned video  : 1;
    } common;
};

struct QQBuddyLevel {
    QQBuddyLevel(const uint8_t* buf, uint32_t);
    uint32_t uid;
    uint32_t onlineTime; // note: the time is presented in seconds
    uint16_t level;
    uint16_t timeRemainder; // note: the time is presented in hours
};

/**
 * 好友状态结构
 * 000-003: 好友QQ号
 * 004: 0x01，未知含义
 * 005-008: 好友IP
 * 009-010: 好友端口
 * 011: 0x01，未知含义
 * 012: 好友状态
 * 013-014: 未知含义
 * 015-030: key，未知含义

*/
struct QQBuddyStatus {
    int getBody(const uint8_t* buf, int len);
    uint32_t uid;
    uint32_t ip;
    uint16_t port;
    uint8_t status;
    // 未知的密钥，会不会是用来加密和好友通讯的一些信息的，
    // 比如点对点通信的时候
    uint8_t unknownKey[QQ_KEY_LENGTH];
};



/**
 * 一个用户的详细信息，全部都是字符串形式，
 * 一共37项
 * 分割符(char)30
 */

/**
 * 1. QQ号
 * 2. 昵称
 * 3. 国家
 * 4. 省
 * 5. 邮政编码
 * 6. 地址
 * 7. 电话
 * 8. 年龄
 * 9. 性别
 * 10. 姓名
 * 11. Email
 * 12. 寻呼机sn，（sn是什么玩意，我也不知道）
 * 13. 寻呼机号
 * 14. 寻呼机服务提供商
 * 15. 寻呼机base num（也不清楚这是什么）
 * 16. 寻呼机类型
 * 17. 职业
 * 18. 主页
 * 19. 认证类型（应该是被人加自己为好友的时候的认证类型把）
 * 20. unknown 1
 * 21. unknown 2
 * 22. 头像，头像是用一个数代表的，比如27, 因为QQ目录下的头像是从1开始编号的，
 *     但是这个头像的数字却是从0开始计数的。并且注意，QQ的目录下面每种头像都
 *     有3个bmp，所以按数字这么一排，27应该是10-1.bmp
 * 23. 手机号
 * 24. 手机类型 
 * 25. 介绍
 * 26. 城市
 * 27. unknown 3
 * 28. unknown 4
 * 29. unknown 5
 * 30. is_open_hp
 * 31. is_open_contact（通讯方式是否对其他人可见）
 * 32. 学校
 * 33. 星座
 * 34. 生肖
 * 35. 血型
 * 36. QQ秀
 * 37. unknown 6，总是0x2D
 */
struct QQContact {
    int buflen;
    char* infobuf;
    const char* infos[QQ_CONTACT_FIELDS];

    QQContact(const char* buf, int len);
    QQContact(const QQContact& rhs);
    QQContact& operator = (const QQContact& rhs);

    ~QQContact() { delete[] infobuf; }
};

/* 在线用户信息(用于搜索用户返回列表中)
 *    i.   用户QQ号的字符串形式
 *    ii.  用户昵称
 *    iii. 用户所在地区
 *    iv.  用户的头像号码
 */
struct QQOnlineUserInfo {
    int getBody(const char* buf, int len);
    uint32_t uid;
    string nickname;
    string province;
    uint16_t face;
};
#endif // _QQ_BUDDY_H_

